package com.example.realm;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.util.StringUtils;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName CustomRealm
 * @Author zhaoluowei
 * @Date 2019/7/1  22:45
 * @Version 1.0
 * @Description 自定义realm
 */

public class CustomRealm extends AuthorizingRealm {
    //构造假数据集合
    private final Map<String, String> map = new ConcurrentHashMap<>();

    {
        map.put("jack", "123");
        map.put("zlw", "456");

    }

    // user --> permission
    private final Map<String, Set<String>> permission = new ConcurrentHashMap<>();

    {

        Set<String> set = new HashSet<>();
        Set<String> set2 = new HashSet<>();

        set.add("buy");
        set.add("query");

        set2.add("add");
        set2.add("update");
        set2.add("delete");

        permission.put("jack", set);
        permission.put("zlw", set2);


    }


    // user --> role
    private final Map<String, Set<String>> roleMap = new ConcurrentHashMap<>();

    {

        Set<String> set = new HashSet<>();
        Set<String> set2 = new HashSet<>();

        set.add("role1");
        set.add("role2");

        set2.add("root");

        roleMap.put("jack", set);
        roleMap.put("zlw", set2);


    }


    /**
     * 授权时候的调用 判断是否有响应的权限
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("授权 doGetAuthorizationInfo");
        String username = (String) principalCollection.getPrimaryPrincipal();

        //一般的获取方式 ：  名称 找 角色 找 权限

        Set<String> permission = getPermissionByNameFromDB(username);
        Set<String> roles = getRolesByNameFromDB(username);

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roles);
        authorizationInfo.setStringPermissions(permission);

        return authorizationInfo;
    }

    /**
     * 登录时候 调用 进行认证
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("认证 doGetAuthenticationInfo");

        //从token中获取用户的信息
        String username = (String) authenticationToken.getPrincipal();
        String password = getPwdByUserNameFromDB(username);
        System.out.println("username --> " + username + "  password --> " + password);

        if (StringUtils.isEmpty(password)) {
            return null;
        }

        //构造一个AuthenticationInfo对象 进行返回
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username, password, this.getName());
        return simpleAuthenticationInfo;
    }

    /**
     * 从数据库中 查询获取用户的信息
     *
     * @param username
     * @return
     */
    private String getPwdByUserNameFromDB(String username) {

        return map.get(username);
    }


    /**
     * 获取用户 所有的角色
     *
     * @param username
     * @return
     */
    private Set<String> getRolesByNameFromDB(String username) {
        return roleMap.get(username);
    }

    //获取权限的集合
    private Set<String> getPermissionByNameFromDB(String username) {
        return permission.get(username);
    }


}
